/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include "../../S_Physics.h"

#include "PBD核心.h"
#include "PBD物理体.h"
#include "GPU解算/PBF邻接构建.h"
//#include "GPU解算/PBF外力解算.h"
#include "GPU解算/PBF邻接构建.h"




struct S_PBF解算器 : public S_Physics {
	S_PDB数据		m_粒子数据;
	S_邻接单元构建	m_邻接;

	
	bool			m_使用GPU计算;
	bool			m_是否重构;
	uint8			m_最大迭代次数;
	float32			m_更新步长;

	//float32			m_K;
	//float32			m_L;
	//float32			m_权重0;



	


	S_设备环境*		m_计算设备;


	uvec3			m_计算维度3D;
	uint32			m_计算维度2D;
	//S_PBF外力计算*	m_外力计算;
	S_邻接索引计算*	m_邻接计算;
	S_邻接索引计算*	m_约束计算数据;
	uint32			m_3D内存用量;
	uint32			m_2D内存用量;
	uint64			m_内存用量;


	S_坐标数据*		m_解算数据;

	
	
	//S_Bullet物理引擎核心	m_Core;
	S_PBF解算器();


	void	f_Update();
	//void	f_Update车辆(S_Px车* 车);
	void	f_应用物理变换();

	//void	f_取更新物体(std::vector<std::vector<Mat44f>>& mat, std::vector<std::vector<void*>>& userData);
	//void	f_取更新物体(std::vector<Mat44f>& mat, std::vector<void*>& userData);
	void	f_取碰撞物体(std::vector<S_碰撞信息>& objs, uint32 scenekey);
	//void	f_等待更新结束();
	void	f_添加物理体(S_物理体* body, uint32 scenekey);
	void	f_移除物理体(S_物理体* body, uint32 scenekey);

	void	f_添加流体(_S_PBF流体* body);



	void	f_添加物理体碰撞回调(S_物理体* body, uint32 scenekey);

	//void	f_重构物理体();
	void	f_销毁物理体(S_物理体* body);

	void	f_重新计算各个物体的粒子索引偏移();

	void	f_施加外力();
	void	f_投影约束();
	//void	f_邻接搜索();
	float32	f_解算密度(uint64 当前ID, const vec3* x, const float32* 质量, const float32 密度0, float32* 密度);
	float32	f_计算拉格朗日乘数(uint64 当前ID, const vec3* x, const float32* 质量, float32 密度, float32 密度0);
	vec3	f_解算密度约束(uint64 当前ID, const vec3* x, const float32* 质量, const float32* 拉格朗日, float32 密度0);
	void	f_更新速度矢量();
	void	f_解算粘度();

	//void	f_构建静态网格碰撞划分();
	void	f_计算静态网格碰撞();



	void	f_初始形状匹配约束();
	void	f_计算形状匹配约束();


	float32	f_更新解算步长(float32 最小步长, float32 最大步长);
	float32 f_权重(vec3 r);
	vec3	f_梯度(vec3 r);
	S_cuAdjacencyIndex	f_getGPU数据();


	uint32					m_飞溅粒子数量;
	std::set<S_物理体*>		m_流体;
	std::set<S_物理体*>		m_刚体;
	std::set<S_物理体*>		m_流入;
	uint64					m_物体添加有效粒子数量;
	//std::vector<S_物理体*>	m_需要重构的物体;
	//bool					m_需要重构物体;

	S_域区*	f_get域属性();
protected:
	std::vector<S_PBF物理体*>	m_动态Body;
	std::vector<S_PBF物理体*>	m_静态Body;



};













